import 'dart:convert';
import 'package:get/get.dart';
import 'package:bot_toast/bot_toast.dart';

import '../../../data/services/playback_service.dart';

/// 录像片段数据模型
class RecordSegment {
  final String id;
  final DateTime startTime;
  final DateTime endTime;
  final String type;
  final int hour;
  final String time;
  final String duration;
  final String source; // 'cloud' 或 'local'
  final String? playUrl; // 新增
  final String? picUrl; // 新增

  RecordSegment({
    required this.id,
    required this.startTime,
    required this.endTime,
    required this.type,
    required this.hour,
    required this.time,
    required this.duration,
    required this.source,
    this.playUrl, // 新增
    this.picUrl, // 新增
  });

  Map<String, dynamic> toMap() {
    return {
      'id': id,
      'startTime': startTime,
      'endTime': endTime,
      'type': type,
      'hour': hour,
      'time': time,
      'duration': duration,
      'source': source,
      'playUrl': playUrl, // 新增
      'picUrl': picUrl, // 新增
    };
  }
}

/// 录像数据管理器
/// 统一处理云端和本地录像数据，提供标准化的数据格式
class RecordDataManager {
  final PlaybackService _playbackService = Get.find<PlaybackService>();

  /// 加载录像数据
  /// [deviceId] 设备ID
  /// [channelId] 通道ID
  /// [date] 日期
  /// [sourceType] 录像源类型：'cloud' 或 'local'
  Future<List<RecordSegment>> loadRecordData({
    required String deviceId,
    required String channelId,
    required DateTime date,
    required String sourceType,
  }) async {
    print('🎬 开始加载录像数据');
    print('🎬 设备ID: $deviceId, 通道ID: $channelId');
    print('🎬 日期: ${_formatDateForAPI(date)}');
    print('🎬 录像源类型: $sourceType');

    try {
      if (sourceType == 'cloud') {
        return await _loadCloudRecords(deviceId, channelId, date);
      } else {
        return await _loadLocalRecords(deviceId, channelId, date);
      }
    } catch (e) {
      print('❌ 加载录像数据失败: $e');
      BotToast.showText(text: '加载录像数据失败，请稍后重试');
      return [];
    }
  }

  /// 加载云端录像数据
  Future<List<RecordSegment>> _loadCloudRecords(
    String deviceId,
    String channelId,
    DateTime date,
  ) async {
    print('📡 调用云端录像API');

    final period = _formatDateForAPI(date);
    final response = await _playbackService.queryDailyRecords(
      serial: deviceId,
      code: channelId.isNotEmpty ? channelId : null,
      period: period,
    );

    print('📡 云端录像API响应: ${jsonEncode(response)}');

    final data = response['data'] as Map<String, dynamic>?;
    if (data == null) {
      print('⚠️ 云端录像数据为空');
      return [];
    }

    final list = data['list'] as List<dynamic>? ?? [];
    print('📡 云端录像列表数量: ${list.length}');

    final segments = <RecordSegment>[];
    for (final record in list) {
      final segment = _parseCloudRecord(record as Map<String, dynamic>);
      if (segment != null) {
        segments.add(segment);
      }
    }

    print('✅ 云端录像数据加载完成，共 ${segments.length} 条记录');
    return segments;
  }

  /// 加载本地录像数据
  Future<List<RecordSegment>> _loadLocalRecords(
    String deviceId,
    String channelId,
    DateTime date,
  ) async {
    print('📡 调用本地录像API');

    final startTime = _formatDateTimeForAPI(date);
    final endTime = _formatDateTimeForAPI(
      date.add(Duration(days: 1)).subtract(Duration(seconds: 1)),
    );

    final response = await _playbackService.getRecordList(
      serial: deviceId,
      code: channelId.isNotEmpty ? channelId : null,
      starttime: startTime,
      endtime: endTime,
      type: 'all',
    );

    print('📡 本地录像API响应: ${jsonEncode(response)}');

    final data = response['data'] as Map<String, dynamic>?;
    if (data == null) {
      print('⚠️ 本地录像数据为空');
      return [];
    }

    final recordList = data['RecordList'] as List<dynamic>? ?? [];
    print('📡 本地录像列表数量: ${recordList.length}');

    final segments = <RecordSegment>[];
    for (final record in recordList) {
      final segment = _parseLocalRecord(record as Map<String, dynamic>);
      if (segment != null) {
        segments.add(segment);
      }
    }

    print('✅ 本地录像数据加载完成，共 ${segments.length} 条记录');
    return segments;
  }

  /// 解析云端录像记录
  RecordSegment? _parseCloudRecord(Map<String, dynamic> recordData) {
    print('📡 处理云端录像记录: ${jsonEncode(recordData)}');

    final startAtStr = recordData['startAt']?.toString();
    final duration = recordData['duration'] as int? ?? 0;
    final type = recordData['type']?.toString() ?? 'motion';
    final hls = recordData['hls']?.toString(); // 新增
    final picUrl = recordData['picUrl']?.toString(); // 新增

    if (startAtStr == null || startAtStr.isEmpty) {
      print('⚠️ 云端录像记录缺少开始时间');
      return null;
    }

    try {
      final startTime = _parseCloudDateTime(startAtStr);
      final endTime = startTime.add(Duration(seconds: duration));

      final segment = RecordSegment(
        id: startAtStr, // 使用开始时间作为ID
        startTime: startTime,
        endTime: endTime,
        type: type,
        hour: startTime.hour,
        time:
            '${startTime.hour.toString().padLeft(2, '0')}:${startTime.minute.toString().padLeft(2, '0')}',
        duration: _formatDuration(duration),
        source: 'cloud',
        playUrl: hls, // 新增
        picUrl: picUrl, // 新增
      );

      print(
        '📡 格式化云端录像记录: ${startTime.hour}:${startTime.minute} - ${endTime.hour}:${endTime.minute}',
      );
      return segment;
    } catch (e) {
      print('❌ 解析云端录像时间失败: $e');
      return null;
    }
  }

  /// 解析本地录像记录
  RecordSegment? _parseLocalRecord(Map<String, dynamic> recordData) {
    print('📡 处理本地录像记录: ${jsonEncode(recordData)}');

    final startTimeStr = recordData['StartTime']?.toString();
    final endTimeStr = recordData['EndTime']?.toString();
    final type = recordData['Type']?.toString() ?? 'motion';
    final id = recordData['DeviceID']?.toString() ?? '';
    final address = recordData['Address']?.toString(); // 新增
    final picUrl = recordData['PicUrl']?.toString(); // 新增

    if (startTimeStr == null || endTimeStr == null) {
      print('⚠️ 本地录像记录缺少时间信息');
      return null;
    }

    try {
      final startTime = _parseLocalDateTime(startTimeStr);
      final endTime = _parseLocalDateTime(endTimeStr);

      final segment = RecordSegment(
        id: id,
        startTime: startTime,
        endTime: endTime,
        type: type,
        hour: startTime.hour,
        time:
            '${startTime.hour.toString().padLeft(2, '0')}:${startTime.minute.toString().padLeft(2, '0')}',
        duration: _formatDuration(endTime.difference(startTime).inSeconds),
        source: 'local',
        playUrl: address, // 新增
        picUrl: picUrl, // 新增
      );

      print(
        '📡 格式化本地录像记录: ${startTime.hour}:${startTime.minute} - ${endTime.hour}:${endTime.minute}',
      );
      return segment;
    } catch (e) {
      print('❌ 解析本地录像时间失败: $e');
      return null;
    }
  }

  /// 格式化日期为API格式 (YYYYMMDD)
  String _formatDateForAPI(DateTime date) {
    return '${date.year}${date.month.toString().padLeft(2, '0')}${date.day.toString().padLeft(2, '0')}';
  }

  /// 格式化日期时间为API格式 (YYYY-MM-DDTHH:mm:ss)
  String _formatDateTimeForAPI(DateTime date) {
    return '${date.year}-${date.month.toString().padLeft(2, '0')}-${date.day.toString().padLeft(2, '0')}T${date.hour.toString().padLeft(2, '0')}:${date.minute.toString().padLeft(2, '0')}:${date.second.toString().padLeft(2, '0')}';
  }

  /// 解析云端日期时间格式 (YYYYMMDDHHmmss)
  DateTime _parseCloudDateTime(String dateTimeStr) {
    if (dateTimeStr.length != 14) {
      throw Exception('云端日期时间格式错误: $dateTimeStr');
    }

    final year = int.parse(dateTimeStr.substring(0, 4));
    final month = int.parse(dateTimeStr.substring(4, 6));
    final day = int.parse(dateTimeStr.substring(6, 8));
    final hour = int.parse(dateTimeStr.substring(8, 10));
    final minute = int.parse(dateTimeStr.substring(10, 12));
    final second = int.parse(dateTimeStr.substring(12, 14));

    return DateTime(year, month, day, hour, minute, second);
  }

  /// 解析本地日期时间格式 (YYYY-MM-DDTHH:mm:ss)
  DateTime _parseLocalDateTime(String dateTimeStr) {
    return DateTime.parse(dateTimeStr);
  }

  /// 格式化时长
  String _formatDuration(int seconds) {
    final minutes = seconds ~/ 60;
    final remainingSeconds = seconds % 60;
    return "${minutes}'${remainingSeconds.toString().padLeft(2, '0')}\"";
  }
}
